package com.tianji.learning.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.tianji.api.client.user.UserClient;
import com.tianji.api.dto.user.UserDTO;
import com.tianji.common.domain.dto.PageDTO;
import com.tianji.common.exceptions.BadRequestException;
import com.tianji.common.utils.BeanUtils;
import com.tianji.common.utils.UserContext;
import com.tianji.learning.domain.dto.ReplyDTO;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.tianji.api.client.user.UserClient;
import com.tianji.api.dto.user.UserDTO;
import com.tianji.common.domain.dto.PageDTO;
import com.tianji.common.utils.BeanUtils;
import com.tianji.common.utils.ObjectUtils;
import com.tianji.learning.domain.po.InteractionReply;
import com.tianji.learning.domain.query.ReplyPageQuery;
import com.tianji.learning.domain.vo.ReplyVO;
import com.tianji.learning.mapper.InteractionReplyMapper;
import com.tianji.learning.service.IInteractionQuestionService;
import com.tianji.learning.service.IInteractionReplyService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

import java.util.*;

import static com.tianji.common.constants.Constant.DATA_FIELD_NAME_CREATE_TIME;
import static com.tianji.common.constants.Constant.DATA_FIELD_NAME_LIKED_TIME;

/**
 * <p>
 * 互动问题的回答或评论 服务实现类
 * </p>
 *
 * @author 东哥
 * @since 2024-06-25
 */
@Service
@RequiredArgsConstructor
public class InteractionReplyServiceImpl extends ServiceImpl<InteractionReplyMapper, InteractionReply> implements IInteractionReplyService {
    private final UserClient userClient;
    private final IInteractionQuestionService questionService;

    /**
     * 分页查询互动回答或评论
     *
     * @param query 查询条件
     * @return 分页数据
     */
    @Override
    public PageDTO<ReplyVO> pageQuery(ReplyPageQuery query) {
        // 1.写入回答或评论
        if (ObjectUtil.isEmpty(query)) {
            return PageDTO.empty(0L, 0L);
        }
        // select * from interaction_reply where answer_id = ? or target_reply_id = ? limit ?,?
        Page<InteractionReply> page = lambdaQuery()
                .eq( InteractionReply::getAnswerId, query.getAnswerId() == null ? 0 :query.getAnswerId())
                .eq(query.getQuestionId()!=null,InteractionReply::getQuestionId,query.getQuestionId())
                .page(query.toMpPageDefaultSortByCreateTimeDesc());
        List<InteractionReply> records = page.getRecords();

        if (ObjectUtil.isEmpty(records)) {
            return PageDTO.empty(page);
        }
        Set<Long> userIds = new HashSet<>();
        for (InteractionReply record : records) {
            if (!record.getHidden()) {
                userIds.add(record.getUserId());
                userIds.add(record.getTargetUserId());
            }
        }
        Map<Long, UserDTO> userMap = new HashMap<>();
        if (ObjectUtil.isNotEmpty(userIds)) {
            List<UserDTO> userDTOS = userClient.queryUserByIds(userIds);
            if (ObjectUtil.isNotEmpty(userDTOS)) {
                userMap = userDTOS.stream().collect(Collectors.toMap(UserDTO::getId, userDTO -> userDTO));
            }
        }
        List<ReplyVO> voList = new ArrayList<>();
        for (InteractionReply record : records) {
            ReplyVO replyVO = BeanUtils.copyBean(record, ReplyVO.class);

            if (!record.getAnonymity()) {
                UserDTO userDTO = userMap.get(record.getUserId());
                if (ObjectUtil.isNotEmpty(userDTO)) {
                    replyVO.setUserName(userDTO.getName());
                    replyVO.setUserIcon(userDTO.getIcon());
                }
            }
            if (ObjectUtil.isNotEmpty(record.getTargetUserId())) {
                UserDTO userDTO = userMap.get(record.getTargetUserId());
                if (ObjectUtil.isNotEmpty(userDTO)) {
                    replyVO.setTargetUserName(userDTO.getName());
                }
            }
            voList.add(replyVO);
        }
        return PageDTO.of(page, voList);
    }

    /**
     * 新增互动回答或评论
     *
     * @param replyDTO 回答或评论信息
     */
    @Override
    @Transactional
    public void saveReply(ReplyDTO replyDTO) {
        if (ObjectUtil.isNull(replyDTO.getContent())) {
            throw new BadRequestException("回答或评论不能为空");
        }

        if (ObjectUtil.isEmpty(replyDTO)) {
            return;
        }
        InteractionReply reply = BeanUtil.toBean(replyDTO, InteractionReply.class);
        if (ObjectUtil.isNotEmpty(reply)) {
            reply.setUserId(UserContext.getUser());
            reply.setReplyTimes(0);
            reply.setLikedTimes(0);
        }
        save(reply);
        if (ObjectUtil.isEmpty(reply.getAnswerId())) {
            questionService.updateOne(replyDTO.getQuestionId(), reply.getId());
        } else {
            lambdaUpdate()
                    .setSql("reply_times = reply_times + 1")
                    .eq(InteractionReply::getId, reply.getAnswerId())
                    .update();
        }

    }





    @Override
    public PageDTO<ReplyVO> queryReplyPage(ReplyPageQuery pageQuery, boolean student) {
        Long questionId = pageQuery.getQuestionId();
        Long answerId = pageQuery.getAnswerId();
        if (ObjectUtils.isEmpty(questionId) && ObjectUtils.isEmpty(answerId)) {
            //学生端
            throw new RuntimeException("问题或回答id不能为空");
        }
        boolean isQueryAnswer  = questionId != null;
        Page<InteractionReply> page = lambdaQuery()
                .eq(isQueryAnswer, InteractionReply::getQuestionId, questionId)
                .eq(InteractionReply::getAnswerId, isQueryAnswer ? 0L : answerId)
                .eq(student, InteractionReply::getHidden, false)
                .page(pageQuery.toMpPage(
                        new OrderItem(DATA_FIELD_NAME_LIKED_TIME, false),
                        new OrderItem(DATA_FIELD_NAME_CREATE_TIME, false)
                ));
        List<InteractionReply> records = page.getRecords();
        if (ObjectUtils.isEmpty(records)) {
            return PageDTO.empty(page);
        }
        // 3.创建集合赋值
        Set<Long> userIds =  new HashSet<>(records.size());  // 提问者id
        Set<Long> answerIds = new HashSet<>(records.size()); // 回答者id
        Set<Long> TargetUserIds =  new HashSet<>(records.size()); // 评论id

        for (InteractionReply record : records) {
            //如果不匿名，或者学生端，则添加提问者id
            if (!record.getAnonymity() || !student) {
                userIds.add(record.getUserId());
            }
            answerIds.add(record.getAnswerId());
            TargetUserIds.add(record.getTargetUserId());
        }

        // 查询目标，如果不是匿名 ， 则查询具体id
        TargetUserIds.remove(0L);
        TargetUserIds.remove(null);
        if (TargetUserIds.size() > 0)
        {
            userIds.addAll(TargetUserIds);
        }

        // 查询用户
        HashMap<Long, UserDTO> objectObjectHashMap = new HashMap<>(userIds.size());
        if (userIds.size() > 0)
        {
            userClient.queryUserByIds(userIds).forEach(userDTO -> objectObjectHashMap.put(userDTO.getId(), userDTO));
        }

        List<ReplyVO> objects = new ArrayList<>(records.size());
        for (InteractionReply record : records) {
            // 拷贝基础属性
            ReplyVO bean = BeanUtils.toBean(record, ReplyVO.class);
            objects.add(bean);
            // 填充回复人信息
            if (!record.getAnonymity() || !student)
            {
                UserDTO userDTO = objectObjectHashMap.get(record.getUserId());

                // 若userDTO不为空，则从userDTO中设置Bean的相关属性
                if (ObjectUtils.isNotEmpty(userDTO)){
                    bean.setUserIcon(userDTO.getIcon()); // 设置用户头像
                    bean.setUserName(userDTO.getName()); // 设置用户名
                    bean.setUserType(userDTO.getType()); // 设置用户类型
                }
            }
            // 如果存在评论的目标，则设置目标用户信息
            if(record.getTargetReplyId() != null)
            {
                UserDTO userDTO = objectObjectHashMap.get(record.getTargetUserId());
                if (ObjectUtils.isNotEmpty(userDTO)){
                    bean.setTargetUserName(userDTO.getName()); // 设置目标用户名
                }
            }

        }
        return new PageDTO<>(page.getTotal(), page.getPages(),objects);
    }
}
